package com.gable.report.service.impl;

import com.gable.report.common.util.MonthEnumUtil;
import com.gable.report.dao.IChartsForAreaMaintainDao;
import com.gable.report.dao.IChartsForAreaMaintenanceDao;
import com.gable.report.model.*;
import com.gable.report.service.ChartsForAreaMaintainInfoService;
import com.gable.report.thread.RedisListStoreThread;
import com.gable.report.thread.RedisValueStoreThread;
import com.gable.report.util.RedisUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

import static com.gable.report.util.ChartsUtil.*;
import static com.gable.report.util.RedisUtil.getAreaModuleKey;


/**
 * Created by lvdouStart on 2017/7/26.
 * 区报表维修情况service实现类
 */
@Service
public class ChartsForAreaMaintainInfoServiceImpl implements ChartsForAreaMaintainInfoService {

    private final Log logger = LogFactory.getLog(this.getClass());

    @Autowired
    IChartsForAreaMaintainDao chartsForAreaMaintainDao;

    @Autowired
    IChartsForAreaMaintenanceDao chartsForAreaMaintenanceDao;

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public Map<String, Object> queryAssetsForOverview(User user, ChartsAreaQuery chartsAreaQuery) throws Exception {
        Map<String, Object> returnMap = new HashMap<>();
        Map<String, Object> paramMap = getParamMap(user, chartsAreaQuery);
        ChartsMaintainInfoView allAssets = getAllAssets(user,paramMap,chartsAreaQuery);
        Map<String,Object> bigRepair;
        Map<String,Object> middleRepair;
        Map<String,Object> smallRepair;
        if(RedisUtil.isOn && isQueryNullOrOnlyType(chartsAreaQuery)) {
            String key1 = getAreaModuleKey("maintain",user,"overview_bigRepair",chartsAreaQuery);
            String key2 = getAreaModuleKey("maintain",user,"overview_middleRepair",chartsAreaQuery);
            String key3 = getAreaModuleKey("maintain",user,"overview_smallRepair",chartsAreaQuery);
            bigRepair = RedisUtil.getValue(redisTemplate, key1);
            middleRepair = RedisUtil.getValue(redisTemplate, key2);
            smallRepair = RedisUtil.getValue(redisTemplate, key3);
            if(bigRepair == null){
                paramMap.put("asId",1);
                paramMap.put("asName","'大维修'");
                paramMap.put("maintainSize",1);
                bigRepair = chartsForAreaMaintainDao.queryMaintainSizeInfo(paramMap);
                paramMap.put("asId",2);
                paramMap.put("asName","'中维修'");
                paramMap.put("maintainSize",2);
                middleRepair = chartsForAreaMaintainDao.queryMaintainSizeInfo(paramMap);
                paramMap.put("asId",3);
                paramMap.put("asName","'小维修'");
                paramMap.put("maintainSize",3);
                smallRepair = chartsForAreaMaintainDao.queryMaintainSizeInfo(paramMap);
                new Thread(new RedisValueStoreThread(redisTemplate, key1, bigRepair)).start();
                new Thread(new RedisValueStoreThread(redisTemplate, key2, middleRepair)).start();
                new Thread(new RedisValueStoreThread(redisTemplate, key3, smallRepair)).start();
            }
        }else{
            paramMap.put("asId",1);
            paramMap.put("asName","'大维修'");
            paramMap.put("maintainSize",1);
            bigRepair = chartsForAreaMaintainDao.queryMaintainSizeInfo(paramMap);
            paramMap.put("asId",2);
            paramMap.put("asName","'中维修'");
            paramMap.put("maintainSize",2);
            middleRepair = chartsForAreaMaintainDao.queryMaintainSizeInfo(paramMap);
            paramMap.put("asId",3);
            paramMap.put("asName","'小维修'");
            paramMap.put("maintainSize",3);
            smallRepair = chartsForAreaMaintainDao.queryMaintainSizeInfo(paramMap);
        }

        returnMap.put("allAssets",allAssets);
        returnMap.put("list", Arrays.asList(bigRepair,middleRepair,smallRepair));
        return returnMap;
    }

    @Override
    public Map<String, Object> queryHospitals(User user, ChartsAreaQuery chartsAreaQuery) throws Exception {
        Map<String, Object> returnMap = new HashMap<>();
        Map<String, Object> paramMap = getParamMap(user, chartsAreaQuery);
        ChartsMaintainInfoView allAssets = getAllAssets(user,paramMap,chartsAreaQuery);
        List<ChartsMaintainInfoView> list;
        //校验必传参数
        if(chartsAreaQuery == null || chartsAreaQuery.getMaintainTag() == null ){
            return null;
        }
        if(RedisUtil.isOn && isQueryNullOrOnlyType(chartsAreaQuery)){
            String key = getAreaModuleKey("maintain",user,"hospital",chartsAreaQuery);
            List redisList = null;
            switch (chartsAreaQuery.getMaintainTag()){
                case 0:
                case 1:
                    key = key +"_tag_01";
                    redisList = RedisUtil.getListValue(redisTemplate, key);
                    list = redisList != null ? redisList : chartsForAreaMaintainDao.queryHospitalsWithCost(paramMap);
                    break;
                case 2:
                    key = key +"_tag_2";
                    redisList = RedisUtil.getListValue(redisTemplate, key);
                    list = redisList != null ? redisList : chartsForAreaMaintainDao.queryHospitalsWithMaintenance(paramMap);
                    break;
                case 3:
                    key = key +"_tag_3";
                    redisList = RedisUtil.getListValue(redisTemplate, key);
                    list = redisList != null ? redisList : chartsForAreaMaintainDao.queryHospitalsWithTime(paramMap);
                    break;
                default:
                    list = null;

            }
            if(redisList == null && list != null){
                // 把数据存入缓存
                new Thread(new RedisListStoreThread(redisTemplate, key, list)).start();
            }
        }else{
            switch (chartsAreaQuery.getMaintainTag()){
                case 0:
                case 1:
                    list = chartsForAreaMaintainDao.queryHospitalsWithCost(paramMap);
                    break;
                case 2:
                    list = chartsForAreaMaintainDao.queryHospitalsWithMaintenance(paramMap);
                    break;
                case 3:
                    list = chartsForAreaMaintainDao.queryHospitalsWithTime(paramMap);
                    break;
                default:
                    list = null;
            }

        }
        //设置平均值方便气泡图四个象限设置
        Double avgPrice = 0.0;
        Double avgEstimateTotalCost = 0.00;
        if(allAssets != null && allAssets.getCurHospitalCounts() != 0 && list != null && list.size() != 0){
            avgPrice = allAssets.getCurDevicePrice()/list.size()*1.0;
            avgEstimateTotalCost = allAssets.getCurEstimateTotalCost()/list.size()*1.0;
        }
        returnMap.put("avgDevicePrice",avgPrice);
        returnMap.put("avgEstimateTotalCost",avgEstimateTotalCost);
        returnMap.put("avgEstimateCostWanyuan",allAssets.getCurEstimateCostWanyuan());
        returnMap.put("list",list);
        return returnMap;
    }

    @Override
    public Map<String, Object> queryDeviceModels(User user, ChartsAreaQuery chartsAreaQuery) throws Exception {
        Map<String, Object> returnMap = new HashMap<>();
        Map<String, Object> paramMap = getParamMap(user, chartsAreaQuery);
        ChartsMaintainInfoView allAssets = getAllAssets(user,paramMap,chartsAreaQuery);
        List<ChartsMaintainInfoView> list;
        //校验必传参数
        if(chartsAreaQuery == null || chartsAreaQuery.getMaintainTag() == null ){
            return null;
        }
        if(RedisUtil.isOn && isQueryNullOrOnlyType(chartsAreaQuery)){
            String key = getAreaModuleKey("maintain",user,"model",chartsAreaQuery);
            List redisList = null;
            switch (chartsAreaQuery.getMaintainTag()){
                case 0:
                case 1:
                    key = key +"_tag_01";
                    redisList = RedisUtil.getListValue(redisTemplate, key);
                    list = redisList != null ? redisList : chartsForAreaMaintainDao.queryDeviceModelsWithCost(paramMap);
                    break;
                case 2:
                    key = key +"_tag_2";
                    redisList = RedisUtil.getListValue(redisTemplate, key);
                    list = redisList != null ? redisList : chartsForAreaMaintainDao.queryDeviceModelsWithMaintenance(paramMap);
                    break;
                case 3:
                    key = key +"_tag_3";
                    redisList = RedisUtil.getListValue(redisTemplate, key);
                    list = redisList != null ? redisList : chartsForAreaMaintainDao.queryDeviceModelsWithTime(paramMap);
                    break;
                default:
                    list = null;

            }
            if(redisList == null && list != null){
                // 把数据存入缓存
                new Thread(new RedisListStoreThread(redisTemplate, key, list)).start();
            }
        }else {
            switch (chartsAreaQuery.getMaintainTag()) {
                case 0:
                case 1:
                    list = chartsForAreaMaintainDao.queryDeviceModelsWithCost(paramMap);
                    break;
                case 2:
                    list = chartsForAreaMaintainDao.queryDeviceModelsWithMaintenance(paramMap);
                    break;
                case 3:
                    list = chartsForAreaMaintainDao.queryDeviceModelsWithTime(paramMap);
                    break;
                default:
                    list = null;
            }
        }
        //设置平均值方便气泡图四个象限设置
        Double avgPrice = 0.0;
        Double avgEstimateTotalCost = 0.00;
        if(allAssets != null && allAssets.getCurHospitalCounts() != 0 && list != null && list.size() != 0){
            avgPrice = allAssets.getCurDevicePrice()/list.size()*1.0;
            avgEstimateTotalCost = allAssets.getCurEstimateTotalCost()/list.size()*1.0;
        }
        returnMap.put("avgDevicePrice",avgPrice);
        returnMap.put("avgEstimateTotalCost",avgEstimateTotalCost);
        returnMap.put("avgEstimateCostWanyuan",allAssets.getCurEstimateCostWanyuan());
        returnMap.put("list",list);
        return returnMap;
    }

    @Override
    public Map<String, Object> queryDeviceTypes(User user, ChartsAreaQuery chartsAreaQuery) throws Exception {
        Map<String, Object> returnMap = new HashMap<>();
        Map<String, Object> paramMap = getParamMap(user, chartsAreaQuery);
        ChartsMaintainInfoView allAssets = getAllAssets(user,paramMap,chartsAreaQuery);
        List<ChartsMaintainInfoView> list;
        //校验必传参数
        if(chartsAreaQuery == null || chartsAreaQuery.getMaintainTag() == null ){
            return null;
        }
        if(RedisUtil.isOn && isQueryNullOrOnlyType(chartsAreaQuery)){
            String key = getAreaModuleKey("maintain",user,"type",chartsAreaQuery);
            List redisList = null;
            switch (chartsAreaQuery.getMaintainTag()){
                case 0:
                case 1:
                    key = key +"_tag_01";
                    redisList = RedisUtil.getListValue(redisTemplate, key);
                    list = redisList != null ? redisList : chartsForAreaMaintainDao.queryDeviceTypesWithCost(paramMap);
                    break;
                case 2:
                    key = key +"_tag_2";
                    redisList = RedisUtil.getListValue(redisTemplate, key);
                    list = redisList != null ? redisList : chartsForAreaMaintainDao.queryDeviceTypesWithMaintenance(paramMap);
                    break;
                case 3:
                    key = key +"_tag_3";
                    redisList = RedisUtil.getListValue(redisTemplate, key);
                    list = redisList != null ? redisList : chartsForAreaMaintainDao.queryDeviceTypesWithTime(paramMap);
                    break;
                default:
                    list = null;

            }
            if(redisList == null && list != null){
                // 把数据存入缓存
                new Thread(new RedisListStoreThread(redisTemplate, key, list)).start();
            }
        }else{
            switch (chartsAreaQuery.getMaintainTag()){
                case 0:
                case 1:
                    list = chartsForAreaMaintainDao.queryDeviceTypesWithCost(paramMap);
                    break;
                case 2:
                    list = chartsForAreaMaintainDao.queryDeviceTypesWithMaintenance(paramMap);
                    break;
                case 3:
                    list = chartsForAreaMaintainDao.queryDeviceTypesWithTime(paramMap);
                    break;
                default:
                    list = null;
            }
        }

        //设置平均值方便气泡图四个象限设置
        Double avgPrice = 0.0;
        Double avgEstimateTotalCost = 0.00;
        if(allAssets != null && allAssets.getCurHospitalCounts() != 0 && list != null && list.size() != 0){
            //二级68分类数量之和
            int size = list.stream().map((x)->x.getList().size()).reduce(0,Integer::sum);
            avgPrice = allAssets.getCurDevicePrice()/size*1.0;
            avgEstimateTotalCost = allAssets.getCurEstimateTotalCost()/size*1.0;
        }
        returnMap.put("avgDevicePrice",avgPrice);
        returnMap.put("avgEstimateTotalCost",avgEstimateTotalCost);
        returnMap.put("avgEstimateCostWanyuan",allAssets.getCurEstimateCostWanyuan());
        returnMap.put("list",list);
        return returnMap;
    }

    @Override
    public Map<String, Object> queryDeviceBrands(User user, ChartsAreaQuery chartsAreaQuery) throws Exception {
        Map<String, Object> returnMap = new HashMap<>();
        Map<String, Object> paramMap = getParamMap(user, chartsAreaQuery);
        List<ChartsMaintainInfoView> list;
        //校验必传参数
        if(chartsAreaQuery == null || chartsAreaQuery.getMaintainTag() == null ){
            return null;
        }
        if(RedisUtil.isOn && isQueryNullOrOnlyType(chartsAreaQuery)){
            String key = getAreaModuleKey("maintain",user,"brand",chartsAreaQuery);
            List redisList = null;
            switch (chartsAreaQuery.getMaintainTag()){
                case 0:
                case 1:
                    key = key +"_tag_01";
                    redisList = RedisUtil.getListValue(redisTemplate, key);
                    list = redisList != null ? redisList : chartsForAreaMaintainDao.queryDeviceBrandsWithCost(paramMap);
                    break;
                case 2:
                    key = key +"_tag_2";
                    redisList = RedisUtil.getListValue(redisTemplate, key);
                    list = redisList != null ? redisList : chartsForAreaMaintainDao.queryDeviceBrandsWithMaintenance(paramMap);
                    break;
                case 3:
                    key = key +"_tag_3";
                    redisList = RedisUtil.getListValue(redisTemplate, key);
                    list = redisList != null ? redisList : chartsForAreaMaintainDao.queryDeviceBrandsWithTime(paramMap);
                    break;
                default:
                    list = null;

            }
            if(redisList == null && list != null){
                // 把数据存入缓存
                new Thread(new RedisListStoreThread(redisTemplate, key, list)).start();
            }
        }else{
            switch (chartsAreaQuery.getMaintainTag()){
                case 0:
                case 1:
                    list = chartsForAreaMaintainDao.queryDeviceBrandsWithCost(paramMap);
                    break;
                case 2:
                    list = chartsForAreaMaintainDao.queryDeviceBrandsWithMaintenance(paramMap);
                    break;
                case 3:
                    list = chartsForAreaMaintainDao.queryDeviceBrandsWithTime(paramMap);
                    break;
                default:
                    list = null;
            }
        }
        returnMap.put("list",list);
        return returnMap;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String, Object> queryForMonth(User user, ChartsAreaQuery chartsAreaQuery) throws Exception {
        Map<String, Object> returnMap = new HashMap<>();
        Map<String, Object> paramMap = getParamMap(user, chartsAreaQuery);
        int curYear = (Integer) paramMap.get("curYear");
        paramMap.put("lastYearEnd",new StringBuffer().append(curYear).append("-1-1").toString());
        paramMap.put("userId",user.getId());
        chartsForAreaMaintainDao.deleteMonthTemp(user.getId());
        chartsForAreaMaintainDao.insertMonthTemp(paramMap);
        List<ChartsMaintainInfoView> list = chartsForAreaMaintainDao.queryForMonth(paramMap);
        for(ChartsMaintainInfoView obj: list){
            obj.setName(MonthEnumUtil.getValue(obj.getId()));
        }
        returnMap.put("list",list);
        return returnMap;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String, Object> queryDeviceInfoByModelName(User user, ChartsAreaQuery chartsAreaQuery) throws Exception {
        Map<String, Object> returnMap = new HashMap<>();
        Map<String, Object> paramMap = getParamMap(user, chartsAreaQuery);
        paramMap.put("userId",user.getId());
        List<ChartsAssetsMaintainInfoView> list ;
        if(RedisUtil.isOn && isQueryNullOrOnlyType(chartsAreaQuery)) {
            //医院key
            String key = getAreaModuleKey("maintain",user,"assets",chartsAreaQuery);
            list = RedisUtil.getListValue(redisTemplate, key);
            if(list == null){
                chartsForAreaMaintainDao.deleteAssetsTemp(user.getId());
                chartsForAreaMaintainDao.insertAssetsTemp(paramMap);
                list = chartsForAreaMaintainDao.queryDeviceInfoByModelName(paramMap);
                new Thread(new RedisListStoreThread(redisTemplate, key, list)).start();
            }
        }else{
            chartsForAreaMaintainDao.deleteAssetsTemp(user.getId());
            chartsForAreaMaintainDao.insertAssetsTemp(paramMap);
            list = chartsForAreaMaintainDao.queryDeviceInfoByModelName(paramMap);
        }
        returnMap.put("list", handleNull(list));
        return returnMap;
    }

    @Override
    public Map<String, Object> queryMaintainRecord(User user, ChartsAreaQuery chartsAreaQuery) throws Exception {
        Map<String, Object> returnMap = new HashMap<>();
        Map<String, Object> paramMap = getParamMap(user, chartsAreaQuery);
        List<ChartsForMaintainRecord> list = chartsForAreaMaintainDao.queryMaintainRecord(paramMap);
        returnMap.put("list", handleNull(list));
        return returnMap;
    }

    @Override
    public Map<String, Object> queryHaltRecord(User user, ChartsAreaQuery chartsAreaQuery) throws Exception {
        Map<String, Object> returnMap = new HashMap<>();
        Map<String, Object> paramMap = getParamMap(user, chartsAreaQuery);
        List<ChartsForMaintainRecord> list = chartsForAreaMaintainDao.queryHaltRecord(paramMap);
        returnMap.put("list", handleNull(list));
        return returnMap;
    }

    @Override
    public ChartsMaintainInfoView getAllAssets(User user,Map paramMap,ChartsAreaQuery chartsAreaQuery) throws Exception{
        ChartsMaintainInfoView allAssets;
        if(RedisUtil.isOn && isQueryNullOrOnlyType(chartsAreaQuery)) {
            //医院key
            String key = getAreaModuleKey("maintain",user,"allAssets",chartsAreaQuery);
            allAssets = RedisUtil.getValue(redisTemplate, key);
            if(allAssets == null){
                allAssets = chartsForAreaMaintainDao.queryAllAssets(paramMap);
                new Thread(new RedisValueStoreThread(redisTemplate, key, allAssets)).start();
            }
        }else{
            allAssets = chartsForAreaMaintainDao.queryAllAssets(paramMap);
        }
        return allAssets;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void setCommonTemp(User user, ChartsAreaQuery chartsAreaQuery) throws Exception {
            //校验必传参数
            Map<String, Object> paramMap = getParamMap(user, chartsAreaQuery);
            paramMap.put("userId",user.getId());
            chartsForAreaMaintainDao.deleteCommonTemp(user.getId());
            chartsForAreaMaintainDao.insertCommonTemp(paramMap);

    }


    /** 
     * @Author: 杨青桦
     * @Description: 维护接口中获取平均保养率和巡检率
     * @Date: 2017/8/10 17:53
     * @param paramMap
     * @return
     */
    private Double[] getAvgOperationRate(Map<String,Object> paramMap){
        Double[] dArray = new Double[2];

        Map<String,Object> upkeepRate = chartsForAreaMaintenanceDao.queryOverviewForUpkeep(paramMap);
        Map<String,Object> inspectionRate = chartsForAreaMaintenanceDao.queryOverviewForInspection(paramMap);
        dArray[0] = (Double)upkeepRate.get("jnUpkeepPercentage");
        dArray[1] = (Double)inspectionRate.get("jnInspectionPercentage");
        return dArray;
    }


}
